#define CHAR_NONE 0
#define CHAR_ATTACK 1
#define CHAR_ENGAGE 2
#define CHAR_BACKUP 3
#define CHAR_LOOT 4
#define CHAR_WAIT 5
#define CHAR_CLEARTARGET 6
#define CHAR_STOPMOVE 7

objectdef CharBase inherits BotBase
{
	variable int MinCombatRange = 10
	variable int MaxCombatRange = 100
	variable bool WillLoot
	variable bool OnlyCash
	variable int WaitUntil = 0

	member WantTarget(string ID)
	{      
		switch ${Spawn[${ID}].Type}
		{
			case me
			case pc
			case pet
			case trainer
			case merchant
			case taskmaster
			case banker
			case broker
			case corpse
				return FALSE
				break
			default	      
				;if ${Math.Distance[${Me.Z},${Spawn[${ID}].Z}]} > 10
				;{
				;	return FALSE
				;}
	      
				;if ${Spawn[${ID}].Level} < ${Math.Calc[${Me.Level} - 5]}
				;{
				;	return FALSE
				;}

				;if ${Spawn[${ID}].Level} > ${Math.Calc[${Me.Level} + 2]}
				;{
				;	return FALSE
				;}
	      
				;if !${Action.InRoamRange[${ID}]}
				;{
				;	return FALSE
				;}
				break
		}
		return TRUE
	}
	
	member NeedPull()
	{
		return FALSE
	}

	method PullPulse()
	{
	}
	 
	member NeedBuff()
	{
		return FALSE
	}
	
	method BuffPulse()
	{
	}
	
	method Sit()
	{
		VGExecute /sit
	}
	
	method Stand()
	{
		VGExecute /stand
	}
	
	member NeedRest()
	{
		if ${Me.HealthPct} < 50
		{
			return TRUE
		}
		return FALSE
	}

	method RestPulse()
	{
	}
	
	method Routine()
	{
		if !${Me.AutoAttackOn}
		{
			VGExecute /autoattacktoggle
		}
		Move:FaceTarget
	}

	method DropOutOfCombat()
	{
		This:ClearTarget()
		if ${Me.InCombat}
		{
			VGExecute /autoattacktoggle
		}
	}
	 
	member AttackState()
	{
		if !${This.DoneWaiting}
		{
			return CHAR_WAIT
		}
		
		if ${Me.Target.Distance} >= ${This.MaxCombatRange}
		{
			return CHAR_ENGAGE
		}
		
		if ${Me.Target.Distance} < ${This.MinCombatRange}
		{
			return CHAR_BACKUP
		}

		if ${Me.Target.Distance} > ${This.MinCombatRange} && ${Me.Target.Distance} < ${This.MaxCombatRange} && ${Move.Moving}
		{
			return CHAR_STOPMOVE
		}
		
		return CHAR_ATTACK
	}

	method AttackPulse()
	{
		This.CurrentState:Set[${This.AttackState}]
		This:EA[${This.CurrentState}]
		switch ${This.CurrentState}
		{
			case CHAR_BACKUP
				Move:FromTargetMelee
				break
			case CHAR_ENGAGE
				Move:ToTargetCombat
				break
			case CHAR_ATTACK
				This:Routine
				break
			case CHAR_STOPMOVE
				Move.StopMovement:Set[TRUE]
				break
			case CHAR_CLEARTARGET
				This:ClearTarget
				break
			case CHAR_WAIT
				break
		}
	}
	 
	method Wait(int MiliSeconds)
	{
		This.WaitUntil:Set[${Math.Calc[${LavishScript.RunningTime} + ${MiliSeconds}]}]
	}
	
	member DoneWaiting()
	{
		if ${This.WaitUntil} < ${LavishScript.RunningTime}
		{
			return TRUE
		}
		return FALSE
	}

	method InitChar()
	{
	}
	 
	method Inject()
	{	
		This:InitChar
	}
	 
	method Shutdown()
	{
	}
}